package io.renren.sf.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.utils.*;
import io.renren.sf.entity.*;
import io.renren.sf.feign.OssFeign;
import io.renren.sf.service.*;
import io.renren.sf.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import io.renren.sf.dao.CbBookDao;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;


@Service("cbBookService")
public class CbBookServiceImpl extends ServiceImpl<CbBookDao, CbBookEntity> implements CbBookService {
    @Autowired
    private CbContentsService cbContentsService;

    @Autowired
    private CbUnitService cbUnitService;

    @Autowired
    private CbChapterService cbChapterService;

    @Autowired
    private CbBasisStrokesService cbBasisStrokesService;

    @Autowired
    private CbStandardBrushService cbStandardBrushService;

    @Autowired
    private CbAppreciationService appreciationService;

    @Autowired
    private CbReadingService readingService;

    @Autowired
    private CbObserveService observeService;

    @Autowired
    private CbBrushService brushService;

    @Autowired
    private CbAnalyzeService analyzeService;

    @Autowired
    private CbContrastService contrastService;

    @Autowired
    private CbPracticeService practiceService;

    @Autowired
    private OssFeign ossFeign;

    @Autowired
    private ThreadPoolExecutor executor;

    @Override
    public Page<CbBookEntity> getChapterByBookId(Map<String, Object> params) {
        String editionId = (String) params.get("editionId");
        long page = Long.parseLong((String) params.get("page"));
        long limit = Long.parseLong((String) params.get("limit"));
        String bookTitle = (String) params.get("bookTitle");
        String bookClassify = (String) params.get("bookClassify");
        QueryWrapper<CbBookEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("border");
        if (!StringUtils.isEmpty(editionId)) {
            queryWrapper.eq("eid", editionId);
        }
        if(!StringUtils.isEmpty(bookTitle)) {
            queryWrapper.eq("book_title", bookTitle);
        }
        if(!StringUtils.isEmpty(bookClassify)) {
            queryWrapper.eq("book_classify", bookClassify);
        }
        Page<CbBookEntity> bookPage = new Page<CbBookEntity>(page, limit);
        baseMapper.selectPage(bookPage, queryWrapper);
        return bookPage;
    }

    @Override
    public synchronized String createZip(Long bookId) throws Exception {
        // 将Long转化成String
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        // 通过bookId查出记录
        CbBookEntity book = baseMapper.selectById(bookId);
        List<CompletableFuture<String>> listFuture = new ArrayList<>();
        CompletableFuture<String> future1 = null, future2 = null, future3 = null, future4 = null, future5 = null, future6 = null, future7 = null, future8 = null, future9 = null, future10 = null, future11 = null;

        if (book.getContentsType() == 0) {
            // 可画目录
            // ===
            future1 = CompletableFuture.supplyAsync(() -> {
                // 1.获取所有目录信息
                List<CbContentsEntity> contentsInfo = cbContentsService.list(new QueryWrapper<CbContentsEntity>().eq("bid", bookId));
                // 没有就直接return ""
                if (CollectionUtils.isEmpty(contentsInfo)) {
                    return "该书存在目录信息未添加";
                }
                for (CbContentsEntity contentsEntity : contentsInfo) {
                    // 1.1生成目录图片
                    String url = contentsEntity.getContents();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在目录图片未添加";
                    }
                    String suffix = url.substring(url.lastIndexOf("."), url.length());
                    String md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());
                    List<CbUnitEntity> unitsInfo = cbUnitService.list(new QueryWrapper<CbUnitEntity>().eq("cid", contentsEntity.getId()));
                    for (CbUnitEntity unitEntity : unitsInfo) {
                        List<CbChapterEntity> chaptersInfo = cbChapterService.list(new QueryWrapper<CbChapterEntity>().eq("uid", unitEntity.getId()));
                        unitEntity.setChapters(chaptersInfo);
                    }
                    contentsEntity.setUnits(unitsInfo);
                }
                // 1.2生成目录json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(contentsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.CONTENT.getName());
                return "";
            }, executor);
            // ===
            // ===
            future2 = CompletableFuture.supplyAsync(() -> {
                // 2.获取所有章节内容通过bookId
                List<CbChapterPictureVo> zjnr = baseMapper.getZJNRByBookId(bookId);
                // 没有就直接return ""
                if (CollectionUtils.isEmpty(zjnr)) {
                    return "该书存在章节内容未添加";
                }
                // 2.1生成章节内容json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(zjnr), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.ZJNR.getName());
                for (CbChapterPictureVo chapterPictureEntity : zjnr) {
                    // 2.2生成章节图片
                    String url = chapterPictureEntity.getChapterPicture();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在章节图片未添加";
                    }
                    String suffix = url.substring(url.lastIndexOf("."), url.length());
                    String md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());
                    // 每个章节图片对应的字体的音视频进行下载  改成位置了
                    List<CbTypefacePositionEntity> wordsInfo = chapterPictureEntity.getTypefacePositions();
                    // 没有就直接return ""
                    if (CollectionUtils.isEmpty(wordsInfo)) {
                        return "该书存在位置信息未添加";
                    }
                    for (CbTypefacePositionEntity typefaceEntity : wordsInfo) {
                        // 2.3生成位置音频
                        String audio = typefaceEntity.getSounds(); // 位置音频可能没有，没有就continue
                        if (StringUtils.isEmpty(audio)) {
                            continue;
                        }
                        String audioSuffix = audio.substring(audio.lastIndexOf("."), audio.length());
                        String audioMd5 = MD5.encrypt(audio) + audioSuffix;
                        Download.download(audio, audioMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future3 = CompletableFuture.supplyAsync(() -> {
                // 3.获取所有欣赏通过bookId
                List<CbAppreciationVo> xsInfo = baseMapper.getXsByBookId(bookId);
                // 可能为空
        /*if(CollectionUtils.isEmpty(xsInfo)){
            return "";
        }*/
                // 3.1生成欣赏json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(xsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.XS.getName());
                for (CbAppreciationVo appreciationEntity : xsInfo) {
                    List<CbAppreciationPictureEntity> xsPicsInfo = appreciationEntity.getPiclist();
                    for (CbAppreciationPictureEntity pictureEntity : xsPicsInfo) {
                        // 3.2生成欣赏图片
                        String url = pictureEntity.getAppreciationPicture();
                        if (StringUtils.isEmpty(url)) {
                            return "该书存在欣赏图片未添加";
                        }
                        String suffix = url.substring(url.lastIndexOf("."), url.length());
                        String md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future4 = CompletableFuture.supplyAsync(() -> {
                // 4.获取所有认读
                List<CbReadingVo> readingsInfo = baseMapper.getRdByBookId(bookId);
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(readingsInfo)){
            return "";
        }*/
                // 4.1生成认读json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(readingsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.RD.getName());
                for (CbReadingVo readingEntity : readingsInfo) {
                    // 4.2生成认读音频
                    String url = readingEntity.getSounds();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在认读音频未添加";
                    }
                    String suffix = url.substring(url.lastIndexOf("."), url.length());
                    String md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());
                    // 4.3生成认读视频
                    String video = readingEntity.getSounds();
                    // 六书演变的视频存在才进行下载
                    if (!StringUtils.isEmpty(video)) {
                        String videoSuffix = video.substring(video.lastIndexOf("."), video.length());
                        String videoMd5 = MD5.encrypt(video) + videoSuffix;
                        Download.download(video, videoMd5, Constant.Zip.PATH.getName());
                    }
                    List<CbReadingPictureEntity> rdPicsInfo = readingEntity.getPiclist();
                    for (CbReadingPictureEntity pictureEntity : rdPicsInfo) {
                        // 4.4生成认读图片
                        String rd = pictureEntity.getReadingPicture();
                        if (StringUtils.isEmpty(rd)) {
                            return "该书存在认读图片未添加";
                        }
                        String rdSuffix = rd.substring(rd.lastIndexOf("."), rd.length());
                        String rdMd5 = MD5.encrypt(rd) + rdSuffix;
                        Download.download(rd, rdMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future5 = CompletableFuture.supplyAsync(() -> {
                // 5.获取观察通过bookId
                List<CbObserveVo> gcsInfo = baseMapper.getGcByBookId(bookId);
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(gcsInfo)){
            return "";
        }*/
                // 5.1生成观察json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(gcsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.GC.getName());
                for (CbObserveVo observeEntity : gcsInfo) {
                    // 5.2生成观察自形特征src
                    String src = observeEntity.getCharacterFeatureSrc();
                    if (StringUtils.isEmpty(src)) {
                        return "该书存在字形特征图片未添加";
                    }
                    String suffix = src.substring(src.lastIndexOf("."), src.length());
                    String md5 = MD5.encrypt(src) + suffix;
                    Download.download(src, md5, Constant.Zip.PATH.getName());
                    // 5.3生成观察字体图片src
                    String otp = observeEntity.getObserveTypefacePicture();
                    if (StringUtils.isEmpty(otp)) {
                        return "该书存在观察字体图片未添加";
                    }
                    String otpSuffix = otp.substring(otp.lastIndexOf("."), otp.length());
                    String otpMd5 = MD5.encrypt(otp) + otpSuffix;
                    Download.download(otp, otpMd5, Constant.Zip.PATH.getName());
                    // 5.4生成笔画位置音频src
                    String spv = observeEntity.getStrokesPositionVideo();
                    if (StringUtils.isEmpty(spv)) {
                        return "该书存在笔画位置音频未添加";
                    }
                    String spvSuffix = spv.substring(spv.lastIndexOf("."), spv.length());
                    String spvMd5 = MD5.encrypt(spv) + spvSuffix;
                    Download.download(spv, spvMd5, Constant.Zip.PATH.getName());
                    List<CbObservePictureEntity> gcPicsInfo = observeEntity.getPiclist();
                    for (CbObservePictureEntity pictureEntity : gcPicsInfo) {
                        // 5.5生成观察图片
                        String pic = pictureEntity.getObservePicture();
                        if (StringUtils.isEmpty(pic)) {
                            return "该书存在观察图片未添加";
                        }
                        String picSuffix = pic.substring(pic.lastIndexOf("."), pic.length());
                        String picMd5 = MD5.encrypt(pic) + picSuffix;
                        Download.download(pic, picMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future6 = CompletableFuture.supplyAsync(() -> {
                // 6.获取所有分析通过bookId
                List<CbAnalyzeEntity> fxsInfo = baseMapper.getFxByBookId(bookId);
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(fxsInfo)){
            return "";
        }*/
                // 6.1生成分析json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(fxsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.FX.getName());
                for (CbAnalyzeEntity analyzeEntity : fxsInfo) {
                    // 6.3生成分析图片
                    String fxPic = analyzeEntity.getAnalyzePicture();
                    if (StringUtils.isEmpty(fxPic)) {
                        return "该书存在分析图片未添加";
                    }
                    String fxPicSuffix = fxPic.substring(fxPic.lastIndexOf("."), fxPic.length());
                    String fxPicMd5 = MD5.encrypt(fxPic) + fxPicSuffix;
                    Download.download(fxPic, fxPicMd5, Constant.Zip.PATH.getName());
                    // 6.4生成分析空间特征语音src
                    String space = analyzeEntity.getSpaceFeatureSounds();
                    if (StringUtils.isEmpty(space)) {
                        return "该书存在分析空间特征语音未添加";
                    }
                    String spaceSuffix = space.substring(space.lastIndexOf("."), space.length());
                    String spaceMd5 = MD5.encrypt(space) + spaceSuffix;
                    Download.download(space, spaceMd5, Constant.Zip.PATH.getName());
                    // 6.5生成分析笔画特征语音src
                    String stokes = analyzeEntity.getStokesFeatureSounds();
                    if (StringUtils.isEmpty(stokes)) {
                        return "该书存在分析笔画特征语音";
                    }
                    String stokesSuffix = stokes.substring(stokes.lastIndexOf("."), stokes.length());
                    String stokesMd5 = MD5.encrypt(stokes) + stokesSuffix;
                    Download.download(stokes, stokesMd5, Constant.Zip.PATH.getName());
                }
                return "";
            }, executor);
            // ===
            // ===
            future7 = CompletableFuture.supplyAsync(() -> {
                // 7.获取所有笔法通过bookId
                List<CbBrushVo> bfsInfo = baseMapper.getBfBybookId(bookId);
                // 获取所有标准笔法视频
                List<CbStandardBrushEntity> bzbfList = cbStandardBrushService.list();
//                if (CollectionUtils.isEmpty(bzbfList)) {
//                    return "标准笔法视频未添加";
//                }
//                for (CbStandardBrushEntity standardBrushEntity : bzbfList) {
//                    // 下载标准笔法视频
//                    String brushVideo = standardBrushEntity.getStandardBrushVideo();
//                    if (StringUtils.isEmpty(brushVideo)) {
//                        return "存在标准笔法视频未添加";
//                    }
//                    String brushVideoSuffix = brushVideo.substring(brushVideo.lastIndexOf("."), brushVideo.length());
//                    String brushVideoMd5 = MD5.encrypt(brushVideo) + brushVideoSuffix;
//                    Download.download(brushVideo, brushVideoMd5, Constant.Zip.PATH.getName());
//                }

                for (CbBrushVo brushEntity : bfsInfo) {
                    //通过字体id获取基本笔画模板数
                    List<CbBasisStrokesEntity> basisStrokesList = cbBasisStrokesService.getJbbhListByTid(brushEntity.getTid());
//                    if(basisStrokesList != null) {
//                        for (CbBasisStrokesEntity strokesEntity : basisStrokesList) {
//                            // 下载基本笔画视频
//                            String wordVideo = strokesEntity.getWordVideo();
//                            if (StringUtils.isEmpty(wordVideo)) {
//                                return "存在基本笔画视频未添加";
//                            }
//                            String wordVideoSuffix = wordVideo.substring(wordVideo.lastIndexOf("."), wordVideo.length());
//                            String wordVideoMd5 = MD5.encrypt(wordVideo) + wordVideoSuffix;
//                            Download.download(wordVideo, wordVideoMd5, Constant.Zip.PATH.getName());
//                        }
//                    }

                    brushEntity.setBasisStrokesList(basisStrokesList);
                    brushEntity.setStandardBrushList(bzbfList);
                    // 7.2生成笔法图片
                    String bfPic = brushEntity.getBrushPicture();
                    if (StringUtils.isEmpty(bfPic)) {
                        return "该书存在笔法图片未添加";
                    }
                    String bfPicSuffix = bfPic.substring(bfPic.lastIndexOf("."), bfPic.length());
                    String bfPicMd5 = MD5.encrypt(bfPic) + bfPicSuffix;
                    Download.download(bfPic, bfPicMd5, Constant.Zip.PATH.getName());
                    // 7.3生成行笔路线gif图
                    String lw = brushEntity.getLineWriting();
                    if (StringUtils.isEmpty(lw)) {
                        return "该书存在行笔路线gif图未添加";
                    }
                    String lwSuffix = lw.substring(lw.lastIndexOf("."), lw.length());
                    String lwMd5 = MD5.encrypt(lw) + lwSuffix;
                    Download.download(lw, lwMd5, Constant.Zip.PATH.getName());
                    // 7.4生成书写动画gif图
                    String cw = brushEntity.getCartoonWriting();
                    if (StringUtils.isEmpty(cw)) {
                        return "该书存在写动画gif图未添加";
                    }
                    String cwSuffix = cw.substring(cw.lastIndexOf("."), cw.length());
                    String cwMd5 = MD5.encrypt(cw) + cwSuffix;
                    Download.download(cw, cwMd5, Constant.Zip.PATH.getName());
                    List<CbBasisStrokesEntity> bfCartoons = brushEntity.getBasisStrokesList();
                }
                // 7.1生成笔法json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(bfsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.BF.getName());
                return "";
            }, executor);
            // ===
            // ===
            future8 = CompletableFuture.supplyAsync(() -> {
                // 8.获取所有视频通过bookId（只需要视频json不需要对应的音视频（因为前面字体的时候下过了））
                List<VideoVo> videosInfo = baseMapper.getVideoByBookId(bookId);
                for (VideoVo videoVo : videosInfo) {
                    String video = videoVo.getVideo();
                    if (StringUtils.isEmpty(video)) {
                        return "该书存在视频未添加";
                    }
                    String videoSuffix = video.substring(video.lastIndexOf("."), video.length());
                    String videoMd5 = MD5.encrypt(video) + videoSuffix;
                    Download.download(video, videoMd5, Constant.Zip.PATH.getName());
                    String sounds = videoVo.getVideoSounds();
                    if (StringUtils.isEmpty(sounds)) {
                        return "该书存在视频解析音频未添加";
                    }
                    String soundsSuffix = sounds.substring(sounds.lastIndexOf("."), sounds.length());
                    String soundsMd5 = MD5.encrypt(sounds) + soundsSuffix;
                    Download.download(sounds, soundsMd5, Constant.Zip.PATH.getName());
                    String bgm = videoVo.getBgm();
                    if (StringUtils.isEmpty(bgm)) {
                        return "该书存在背景音乐未添加";
                    }
                    String bgmSuffix = bgm.substring(bgm.lastIndexOf("."), bgm.length());
                    String bgmMd5 = MD5.encrypt(bgm) + bgmSuffix;
                    Download.download(bgm, bgmMd5, Constant.Zip.PATH.getName());
                }
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(videosInfo)){
            return "";
        }*/
                // 8.1生成视频json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(videosInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.VIDEO.getName());
                return "";
            }, executor);
            // ===
            // ===
            future9 = CompletableFuture.supplyAsync(() -> {
                // 9.获取所有对比通过bookId
                List<CbContrastVo> dbsInfo = baseMapper.getDbByBookId(bookId);
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(dbsInfo)){
            return "";
        }*/
                // 9.1生成对比json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(dbsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.DB.getName());
                for (CbContrastVo contrastEntity : dbsInfo) {
                    List<CbContrastTypefaceEntity> dbPicsInfo = contrastEntity.getContrastTypefaces();
                    for (CbContrastTypefaceEntity dbPic : dbPicsInfo) {
                        // 9.2生成对比子图
                        String sonpic = dbPic.getContrastSonpic();
                        if (StringUtils.isEmpty(sonpic)) {
                            return "该书存在对比子图未添加";
                        }
                        String sonpicSuffix = sonpic.substring(sonpic.lastIndexOf("."), sonpic.length());
                        String sonpicMd5 = MD5.encrypt(sonpic) + sonpicSuffix;
                        Download.download(sonpic, sonpicMd5, Constant.Zip.PATH.getName());
                        // 9.2生成对比视频src
                        String dbVideo = dbPic.getContrastVideo();
                        if (StringUtils.isEmpty(dbVideo)) {
                            return "该书存在对比视频未添加";
                        }
                        String dbVideoSuffix = dbVideo.substring(dbVideo.lastIndexOf("."), dbVideo.length());
                        String dbVideoMd5 = MD5.encrypt(dbVideo) + dbVideoSuffix;
                        Download.download(dbVideo, dbVideoMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future10 = CompletableFuture.supplyAsync(() -> {
                // 10.获取所有随堂练习通过bookId
                List<CbPracticeEntity> stlxsInfo = baseMapper.getStlxByBookId(bookId);
                // 没有就直接return ""
        /*if(CollectionUtils.isEmpty(stlxsInfo)){
            return "";
        }*/
                // 10.1生成随堂练习json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(stlxsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.STLX.getName());
                for (CbPracticeEntity practiceEntity : stlxsInfo) {
                    // 10.2生成观察书写图片
                    String gcsx = practiceEntity.getGcsxPicture();
                    if (StringUtils.isEmpty(gcsx)) {
                        return "该书存在观察书写图片未添加";
                    }
                    String gcsxSuffix = gcsx.substring(gcsx.lastIndexOf("."), gcsx.length());
                    String gcsxMd5 = MD5.encrypt(gcsx) + gcsxSuffix;
                    Download.download(gcsx, gcsxMd5, Constant.Zip.PATH.getName());
                    // 10.3生成对比描红图片
                    String dbmh = practiceEntity.getDbmhPicture();
                    if (StringUtils.isEmpty(dbmh)) {
                        return "该书存在对比描红图片未添加";
                    }
                    String dbmhSuffix = dbmh.substring(dbmh.lastIndexOf("."), dbmh.length());
                    String dbmhMd5 = MD5.encrypt(dbmh) + dbmhSuffix;
                    Download.download(dbmh, dbmhMd5, Constant.Zip.PATH.getName());
                    // 10.4生成调整描红图片
                    String tzmh = practiceEntity.getTzmhPicture();
                    if (StringUtils.isEmpty(tzmh)) {
                        return "该书存在调整描红图片未添加";
                    }
                    String tzmhSuffix = tzmh.substring(tzmh.lastIndexOf("."), tzmh.length());
                    String tzmhMd5 = MD5.encrypt(tzmh) + tzmhSuffix;
                    Download.download(tzmh, tzmhMd5, Constant.Zip.PATH.getName());
                    // 10.5生成双钩填写图片
                    String sgtx = practiceEntity.getSgtxPicture();
                    if (StringUtils.isEmpty(sgtx)) {
                        return "该书存在双钩填写图片未添加";
                    }
                    String sgtxSuffix = sgtx.substring(sgtx.lastIndexOf("."), sgtx.length());
                    String sgtxMd5 = MD5.encrypt(sgtx) + sgtxSuffix;
                    Download.download(sgtx, sgtxMd5, Constant.Zip.PATH.getName());
                }
                return "";
            }, executor);
            future11 = CompletableFuture.supplyAsync(() -> {
                List<CbButtonVo> buttonVoList = new ArrayList<>();
                List<CbTypefaceEntity> typefaceEntityList = baseMapper.getTypefaceByBookId(bookId);
                for (CbTypefaceEntity typeface : typefaceEntityList) {
                    CbButtonVo cbButtonVo = new CbButtonVo();
                    Long tid = typeface.getId();
                    List<String> buttonList = new ArrayList<>();
                    List<CbAppreciationEntity> appreciations = appreciationService.list(new QueryWrapper<CbAppreciationEntity>().eq("tid", tid));
                    List<CbReadingEntity> readings = readingService.list(new QueryWrapper<CbReadingEntity>().eq("tid", tid));
                    List<CbObserveEntity> observes = observeService.list(new QueryWrapper<CbObserveEntity>().eq("tid", tid));
                    List<CbAnalyzeEntity> analyzes = analyzeService.list(new QueryWrapper<CbAnalyzeEntity>().eq("tid", tid));
                    List<CbBrushEntity> brushs = brushService.list(new QueryWrapper<CbBrushEntity>().eq("tid", tid));
                    List<CbContrastEntity> contrasts = contrastService.list(new QueryWrapper<CbContrastEntity>().eq("tid", tid));
                    List<CbPracticeEntity> practices = practiceService.list(new QueryWrapper<CbPracticeEntity>().eq("tid", tid));
                    if (appreciations.size() > 0) buttonList.add("欣赏");
                    if (readings.size() > 0) buttonList.add("认读");
                    if (observes.size() > 0) buttonList.add("观察");
                    if (analyzes.size() > 0) buttonList.add("分析");
                    if (brushs.size() > 0) buttonList.add("笔法");
                    if (typeface.getVideo() != null) buttonList.add("视频");
                    if (contrasts.size() > 0) buttonList.add("对比");
                    if (practices.size() > 0) buttonList.add("随堂练习");
                    cbButtonVo.setId(tid).setButtonList(buttonList);
                    buttonVoList.add(cbButtonVo);
                }
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(buttonVoList), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.QBBUTTON.getName());
                return "";
            }, executor);
        } else {
            // 固定目录
            // ===
            future1 = CompletableFuture.supplyAsync(() -> {
                // 1.获取固定目录
                List<CbFixUnitVo> fixUnitList = baseMapper.getFixUnitList(bookId);
                // 没有就直接return ""
                if (CollectionUtils.isEmpty(fixUnitList)) {
                    return "该书存在固定目录未添加";
                }
                // 1.1生成固定目录json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(fixUnitList), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.Fix_CONTENT.getName());
                return "";
            }, executor);
            // ===
            // ===
            future2 = CompletableFuture.supplyAsync(() -> {
                // 2.获取固定章节下字体
                List<CbTypefaceVo> wordList = baseMapper.getWordList(bookId);
                // 没有就直接return ""
                if (CollectionUtils.isEmpty(wordList)) {
                    return "该书存在字体未添加";
                }
                // 2.1生成固定目录json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(wordList), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.Fix_CHAPTER_WORD.getName());
                for (CbTypefaceVo word : wordList) {
                    String url = word.getBgm();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在bgm未添加";
                    }
                    String suffix = url.substring(url.lastIndexOf("."), url.length());
                    String md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());

                    url = word.getVideo();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在video未添加";
                    }
                    suffix = url.substring(url.lastIndexOf("."), url.length());
                    md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());

                    url = word.getTypefacePicture();
                    if (!StringUtils.isEmpty(url)) {
                        suffix = url.substring(url.lastIndexOf("."), url.length());
                        md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.Zip.PATH.getName());
                    }

                    url = word.getVideo2();
                    if (!StringUtils.isEmpty(url)) {
                        suffix = url.substring(url.lastIndexOf("."), url.length());
                        md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.Zip.PATH.getName());
                    }

                    url = word.getVideo3();
                    if (!StringUtils.isEmpty(url)) {
                        suffix = url.substring(url.lastIndexOf("."), url.length());
                        md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future3 = CompletableFuture.supplyAsync(() -> {
                // 3.获取所有欣赏通过bookId
                List<CbAppreciationVo> xsInfo = baseMapper.getXsByBookId2(bookId);
                // 3.1生成欣赏json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(xsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.XS.getName());
                for (CbAppreciationVo appreciationEntity : xsInfo) {
                    List<CbAppreciationPictureEntity> xsPicsInfo = appreciationEntity.getPiclist();
                    for (CbAppreciationPictureEntity pictureEntity : xsPicsInfo) {
                        // 3.2生成欣赏图片
                        String url = pictureEntity.getAppreciationPicture();
                        if (StringUtils.isEmpty(url)) {
                            return "该书存在欣赏图片未添加";
                        }
                        String suffix = url.substring(url.lastIndexOf("."), url.length());
                        String md5 = MD5.encrypt(url) + suffix;
                        Download.download(url, md5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future4 = CompletableFuture.supplyAsync(() -> {
                // 4.获取所有认读
                List<CbReadingVo> readingsInfo = baseMapper.getRdByBookId2(bookId);
                // 4.1生成认读json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(readingsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.RD.getName());
                for (CbReadingVo readingEntity : readingsInfo) {
                    // 4.2生成认读音频
                    String url = readingEntity.getSounds();
                    if (StringUtils.isEmpty(url)) {
                        return "该书存在认读音频未添加";
                    }
                    String suffix = url.substring(url.lastIndexOf("."), url.length());
                    String md5 = MD5.encrypt(url) + suffix;
                    Download.download(url, md5, Constant.Zip.PATH.getName());
                    // 4.3生成认读视频
                    String video = readingEntity.getSounds();
                    // 六书演变的视频存在才进行下载
                    if (!StringUtils.isEmpty(video)) {
                        String videoSuffix = video.substring(video.lastIndexOf("."), video.length());
                        String videoMd5 = MD5.encrypt(video) + videoSuffix;
                        Download.download(video, videoMd5, Constant.Zip.PATH.getName());
                    }
                    List<CbReadingPictureEntity> rdPicsInfo = readingEntity.getPiclist();
                    for (CbReadingPictureEntity pictureEntity : rdPicsInfo) {
                        // 4.4生成认读图片
                        String rd = pictureEntity.getReadingPicture();
                        if (StringUtils.isEmpty(rd)) {
                            return "该书存在认读图片未添加";
                        }
                        String rdSuffix = rd.substring(rd.lastIndexOf("."), rd.length());
                        String rdMd5 = MD5.encrypt(rd) + rdSuffix;
                        Download.download(rd, rdMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future5 = CompletableFuture.supplyAsync(() -> {
                // 5.获取观察通过bookId
                List<CbObserveVo> gcsInfo = baseMapper.getGcByBookId2(bookId);
                // 5.1生成观察json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(gcsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.GC.getName());
                for (CbObserveVo observeEntity : gcsInfo) {
                    // 5.2生成观察自形特征src
                    String src = observeEntity.getCharacterFeatureSrc();
                    if (StringUtils.isEmpty(src)) {
                        return "该书存在字形特征图片未添加";
                    }
                    String suffix = src.substring(src.lastIndexOf("."), src.length());
                    String md5 = MD5.encrypt(src) + suffix;
                    Download.download(src, md5, Constant.Zip.PATH.getName());
                    // 5.3生成观察字体图片src
                    String otp = observeEntity.getObserveTypefacePicture();
                    if (StringUtils.isEmpty(otp)) {
                        return "该书存在观察字体图片未添加";
                    }
                    String otpSuffix = otp.substring(otp.lastIndexOf("."), otp.length());
                    String otpMd5 = MD5.encrypt(otp) + otpSuffix;
                    Download.download(otp, otpMd5, Constant.Zip.PATH.getName());
                    // 5.4生成笔画位置音频src
                    String spv = observeEntity.getStrokesPositionVideo();
                    if (StringUtils.isEmpty(spv)) {
                        return "该书存在笔画位置音频未添加";
                    }
                    String spvSuffix = spv.substring(spv.lastIndexOf("."), spv.length());
                    String spvMd5 = MD5.encrypt(spv) + spvSuffix;
                    Download.download(spv, spvMd5, Constant.Zip.PATH.getName());
                    List<CbObservePictureEntity> gcPicsInfo = observeEntity.getPiclist();
                    for (CbObservePictureEntity pictureEntity : gcPicsInfo) {
                        // 5.5生成观察图片
                        String pic = pictureEntity.getObservePicture();
                        if (StringUtils.isEmpty(pic)) {
                            return "该书存在观察图片未添加";
                        }
                        String picSuffix = pic.substring(pic.lastIndexOf("."), pic.length());
                        String picMd5 = MD5.encrypt(pic) + picSuffix;
                        Download.download(pic, picMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future6 = CompletableFuture.supplyAsync(() -> {
                // 6.获取所有分析通过bookId
                List<CbAnalyzeEntity> fxsInfo = baseMapper.getFxByBookId2(bookId);
                // 6.1生成分析json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(fxsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.FX.getName());
                for (CbAnalyzeEntity analyzeEntity : fxsInfo) {
                    // 6.3生成分析图片
                    String fxPic = analyzeEntity.getAnalyzePicture();
                    if (StringUtils.isEmpty(fxPic)) {
                        return "该书存在分析图片未添加";
                    }
                    String fxPicSuffix = fxPic.substring(fxPic.lastIndexOf("."), fxPic.length());
                    String fxPicMd5 = MD5.encrypt(fxPic) + fxPicSuffix;
                    Download.download(fxPic, fxPicMd5, Constant.Zip.PATH.getName());
                    // 6.4生成分析空间特征语音src
                    String space = analyzeEntity.getSpaceFeatureSounds();
                    if (StringUtils.isEmpty(space)) {
                        return "该书存在分析空间特征语音未添加";
                    }
                    String spaceSuffix = space.substring(space.lastIndexOf("."), space.length());
                    String spaceMd5 = MD5.encrypt(space) + spaceSuffix;
                    Download.download(space, spaceMd5, Constant.Zip.PATH.getName());
                    // 6.5生成分析笔画特征语音src
                    String stokes = analyzeEntity.getStokesFeatureSounds();
                    if (StringUtils.isEmpty(stokes)) {
                        return "该书存在分析笔画特征语音";
                    }
                    String stokesSuffix = stokes.substring(stokes.lastIndexOf("."), stokes.length());
                    String stokesMd5 = MD5.encrypt(stokes) + stokesSuffix;
                    Download.download(stokes, stokesMd5, Constant.Zip.PATH.getName());
                }
                return "";
            }, executor);
            // ===
            // ===
            future7 = CompletableFuture.supplyAsync(() -> {
                // 7.获取所有笔法通过bookId
                List<CbBrushVo> bfsInfo = baseMapper.getBfBybookId2(bookId);
                // 获取所有基本笔画视频
                List<CbBasisStrokesEntity> jbbhList = cbBasisStrokesService.list();
                if (CollectionUtils.isEmpty(jbbhList)) {
                    return "基本笔画视频未添加";
                }
                for (CbBasisStrokesEntity strokesEntity : jbbhList) {
                    // 下载基本笔画视频
                    String wordVideo = strokesEntity.getWordVideo();
                    if (StringUtils.isEmpty(wordVideo)) {
                        return "存在基本笔画视频未添加";
                    }
                    String wordVideoSuffix = wordVideo.substring(wordVideo.lastIndexOf("."), wordVideo.length());
                    String wordVideoMd5 = MD5.encrypt(wordVideo) + wordVideoSuffix;
                    Download.download(wordVideo, wordVideoMd5, Constant.Zip.PATH.getName());
                }
                // 获取所有标准笔法视频
                List<CbStandardBrushEntity> bzbfList = cbStandardBrushService.list();
                if (CollectionUtils.isEmpty(bzbfList)) {
                    return "标准笔法视频未添加";
                }
                for (CbStandardBrushEntity standardBrushEntity : bzbfList) {
                    // 下载标准笔法视频
                    String brushVideo = standardBrushEntity.getStandardBrushVideo();
                    if (StringUtils.isEmpty(brushVideo)) {
                        return "存在标准笔法视频未添加";
                    }
                    String brushVideoSuffix = brushVideo.substring(brushVideo.lastIndexOf("."), brushVideo.length());
                    String brushVideoMd5 = MD5.encrypt(brushVideo) + brushVideoSuffix;
                    Download.download(brushVideo, brushVideoMd5, Constant.Zip.PATH.getName());
                }

                for (CbBrushVo brushEntity : bfsInfo) {
                    brushEntity.setBasisStrokesList(jbbhList);
                    brushEntity.setStandardBrushList(bzbfList);
                    // 7.2生成笔法图片
                    String bfPic = brushEntity.getBrushPicture();
                    if (StringUtils.isEmpty(bfPic)) {
                        return "该书存在笔法图片未添加";
                    }
                    String bfPicSuffix = bfPic.substring(bfPic.lastIndexOf("."), bfPic.length());
                    String bfPicMd5 = MD5.encrypt(bfPic) + bfPicSuffix;
                    Download.download(bfPic, bfPicMd5, Constant.Zip.PATH.getName());
                    // 7.3生成行笔路线gif图
                    String lw = brushEntity.getLineWriting();
                    if (StringUtils.isEmpty(lw)) {
                        return "该书存在行笔路线gif图未添加";
                    }
                    String lwSuffix = lw.substring(lw.lastIndexOf("."), lw.length());
                    String lwMd5 = MD5.encrypt(lw) + lwSuffix;
                    Download.download(lw, lwMd5, Constant.Zip.PATH.getName());
                    // 7.4生成书写动画gif图
                    String cw = brushEntity.getCartoonWriting();
                    if (StringUtils.isEmpty(cw)) {
                        return "该书存在写动画gif图未添加";
                    }
                    String cwSuffix = cw.substring(cw.lastIndexOf("."), cw.length());
                    String cwMd5 = MD5.encrypt(cw) + cwSuffix;
                    Download.download(cw, cwMd5, Constant.Zip.PATH.getName());
                    List<CbBasisStrokesEntity> bfCartoons = brushEntity.getBasisStrokesList();
                }
                // 7.1生成笔法json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(bfsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.BF.getName());
                return "";
            }, executor);
            // ===
            // ===
            future8 = CompletableFuture.supplyAsync(() -> {
                // 8.获取所有视频通过bookId（只需要视频json不需要对应的音视频（因为前面字体的时候下过了））
                List<VideoVo> videosInfo = baseMapper.getVideoByBookId2(bookId);
                // 8.1生成视频json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(videosInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.VIDEO.getName());
                return "";
            }, executor);
            // ===
            // ===
            future9 = CompletableFuture.supplyAsync(() -> {
                // 9.获取所有对比通过bookId
                List<CbContrastVo> dbsInfo = baseMapper.getDbByBookId2(bookId);
                // 9.1生成对比json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(dbsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.DB.getName());
                for (CbContrastVo contrastEntity : dbsInfo) {
                    List<CbContrastTypefaceEntity> dbPicsInfo = contrastEntity.getContrastTypefaces();
                    for (CbContrastTypefaceEntity dbPic : dbPicsInfo) {
                        // 9.2生成对比子图
                        String sonpic = dbPic.getContrastSonpic();
                        if (StringUtils.isEmpty(sonpic)) {
                            return "该书存在对比子图未添加";
                        }
                        String sonpicSuffix = sonpic.substring(sonpic.lastIndexOf("."), sonpic.length());
                        String sonpicMd5 = MD5.encrypt(sonpic) + sonpicSuffix;
                        Download.download(sonpic, sonpicMd5, Constant.Zip.PATH.getName());
                        // 9.2生成对比视频src
                        String dbVideo = dbPic.getContrastVideo();
                        if (StringUtils.isEmpty(dbVideo)) {
                            return "该书存在对比视频未添加";
                        }
                        String dbVideoSuffix = dbVideo.substring(dbVideo.lastIndexOf("."), dbVideo.length());
                        String dbVideoMd5 = MD5.encrypt(dbVideo) + dbVideoSuffix;
                        Download.download(dbVideo, dbVideoMd5, Constant.Zip.PATH.getName());
                    }
                }
                return "";
            }, executor);
            // ===
            // ===
            future10 = CompletableFuture.supplyAsync(() -> {
                // 10.获取所有随堂练习通过bookId
                List<CbPracticeEntity> stlxsInfo = baseMapper.getStlxByBookId2(bookId);
                // 10.1生成随堂练习json
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(stlxsInfo), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.STLX.getName());
                for (CbPracticeEntity practiceEntity : stlxsInfo) {
                    // 10.2生成观察书写图片
                    String gcsx = practiceEntity.getGcsxPicture();
                    if (StringUtils.isEmpty(gcsx)) {
                        return "该书存在观察书写图片未添加";
                    }
                    String gcsxSuffix = gcsx.substring(gcsx.lastIndexOf("."), gcsx.length());
                    String gcsxMd5 = MD5.encrypt(gcsx) + gcsxSuffix;
                    Download.download(gcsx, gcsxMd5, Constant.Zip.PATH.getName());
                    // 10.3生成对比描红图片
                    String dbmh = practiceEntity.getDbmhPicture();
                    if (StringUtils.isEmpty(dbmh)) {
                        return "该书存在对比描红图片未添加";
                    }
                    String dbmhSuffix = dbmh.substring(dbmh.lastIndexOf("."), dbmh.length());
                    String dbmhMd5 = MD5.encrypt(dbmh) + dbmhSuffix;
                    Download.download(dbmh, dbmhMd5, Constant.Zip.PATH.getName());
                    // 10.4生成调整描红图片
                    String tzmh = practiceEntity.getTzmhPicture();
                    if (StringUtils.isEmpty(tzmh)) {
                        return "该书存在调整描红图片未添加";
                    }
                    String tzmhSuffix = tzmh.substring(tzmh.lastIndexOf("."), tzmh.length());
                    String tzmhMd5 = MD5.encrypt(tzmh) + tzmhSuffix;
                    Download.download(tzmh, tzmhMd5, Constant.Zip.PATH.getName());
                    // 10.5生成双钩填写图片
                    String sgtx = practiceEntity.getSgtxPicture();
                    if (StringUtils.isEmpty(sgtx)) {
                        return "该书存在双钩填写图片未添加";
                    }
                    String sgtxSuffix = sgtx.substring(sgtx.lastIndexOf("."), sgtx.length());
                    String sgtxMd5 = MD5.encrypt(sgtx) + sgtxSuffix;
                    Download.download(sgtx, sgtxMd5, Constant.Zip.PATH.getName());
                }
                return "";
            }, executor);
            future11 = CompletableFuture.supplyAsync(() -> {
                List<CbButtonVo> buttonVoList = new ArrayList<>();
                List<CbTypefaceEntity> typefaceEntityList = baseMapper.getTypefaceByBookId2(bookId);
                for (CbTypefaceEntity typeface : typefaceEntityList) {
                    CbButtonVo cbButtonVo = new CbButtonVo();
                    Long tid = typeface.getId();
                    List<String> buttonList = new ArrayList<>();
                    List<CbAppreciationEntity> appreciations = appreciationService.list(new QueryWrapper<CbAppreciationEntity>().eq("tid", tid));
                    List<CbReadingEntity> readings = readingService.list(new QueryWrapper<CbReadingEntity>().eq("tid", tid));
                    List<CbObserveEntity> observes = observeService.list(new QueryWrapper<CbObserveEntity>().eq("tid", tid));
                    List<CbAnalyzeEntity> analyzes = analyzeService.list(new QueryWrapper<CbAnalyzeEntity>().eq("tid", tid));
                    List<CbBrushEntity> brushs = brushService.list(new QueryWrapper<CbBrushEntity>().eq("tid", tid));
                    List<CbContrastEntity> contrasts = contrastService.list(new QueryWrapper<CbContrastEntity>().eq("tid", tid));
                    List<CbPracticeEntity> practices = practiceService.list(new QueryWrapper<CbPracticeEntity>().eq("tid", tid));
                    if (appreciations.size() > 0) buttonList.add("欣赏");
                    if (readings.size() > 0) buttonList.add("认读");
                    if (observes.size() > 0) buttonList.add("观察");
                    if (analyzes.size() > 0) buttonList.add("分析");
                    if (brushs.size() > 0) buttonList.add("笔法");
                    if (typeface.getVideo() != null) buttonList.add("视频");
                    if (contrasts.size() > 0) buttonList.add("对比");
                    if (practices.size() > 0) buttonList.add("随堂练习");
                    cbButtonVo.setId(tid).setButtonList(buttonList);
                    buttonVoList.add(cbButtonVo);
                }
                Download.createJsonFile(JSON.toJSONString(ResponseData.success(buttonVoList), serializeConfig), Constant.Zip.PATH.getName(), Constant.Zip.QBBUTTON.getName());
                return "";
            }, executor);
        }
        listFuture.add(future1);
        listFuture.add(future2);
        listFuture.add(future3);
        listFuture.add(future4);
        listFuture.add(future5);
        listFuture.add(future6);
        listFuture.add(future7);
        listFuture.add(future8);
        listFuture.add(future9);
        listFuture.add(future10);
        listFuture.add(future11);
        CompletableFuture.allOf(listFuture.toArray(new CompletableFuture[]{})).get();

        // ===
        for (CompletableFuture<String> future : listFuture) {
            if (!StringUtils.isEmpty(future.get())) {
                return future.get();
            }
        }

        // 将e:\\hanzhiZip\\下的文件打成压缩包
        // 得到file数组
        File[] files = getFiles(Constant.Zip.PATH.getName());
        String zipPath = Constant.Zip.YSB.getName() + bookId + ".zip";
        File zipFile = new File(zipPath); // zip存放路径
        ZipMultiFile.zipFiles(files, zipFile);
        R upload = ossFeign.uploadZip(zipPath);// 上传至oss
        return (String) upload.get("url");
    }

    @Override
    public List<BookEditionInfoVo> getAllBookEditionInfoVo() {
        return this.baseMapper.getAllBookEditionInfoVo();
    }

    private File[] getFiles(String path) {
        File dir = new File(path);
        return dir.listFiles();
    }
}
